package com.rockcent.mall.controller;

import com.rockcent.common.common.JsonResult;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.RestDoing;
import com.rockcent.common.controller.BaseController;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.BigDecimalUtils;
import com.rockcent.common.utils.RDateFormatUtils;
import com.rockcent.common.utils.RDateUtils;
import com.rockcent.mall.Routes;
import com.rockcent.mall.lib.domain.MallOrder;
import com.rockcent.mall.lib.domain.MerchantOrder;
import com.rockcent.mall.lib.domain.MerchantOrderItem;
import com.rockcent.mall.lib.domain.enumclass.*;
import com.rockcent.mall.lib.dto.MerchantOrderItemDto;
import com.rockcent.mall.lib.dto.ProductDto;
import com.rockcent.mall.lib.dto.SettlementRecordDto;
import com.rockcent.mall.lib.dto.UserInfoDto;
import com.rockcent.mall.lib.helper.BaseUserHelper;
import com.rockcent.mall.lib.repository.*;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by DK on 16/11/10.
 */
@RestController
public class MerchantSettlementRecordController extends BaseController {

    private final Logger log = LoggerFactory.getLogger(MerchantSettlementRecordController.class);

    @Autowired
    private BaseUserHelper userHelper;

    @Autowired
    private MerchantProductRepository merchantProductRepository;

    @Autowired
    private MerchantOrderItemRepository merchantOrderItemRepository;

    @Autowired
    private MerchantOrderRepository merchantOrderRepository;

    /**
     * @api {get} /merchant/income/collect/page 收入汇总 分页
     * @apiGroup MERCHANT_INCOME_COLLECT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String=ALL("全部"), GOODS("商品"), SERVICE("服务")} productType <code>必传参数</code> 产品类型 默认ALL
     * @apiParam {String=MARKET("分销收入"), SELF("自营收入")} productSource <code>必传参数</code> 产品来源 默认SELF
     * @apiParam {String} beginDate  开始时间
     * @apiParam {String} endDate  结束时间
     * @apiParam {String} keyword  产品名称/编号
     * @apiParam {boolean} refundable  是否可退
     *
     * @apiSuccess {Long} id 产品ID
     * @apiSuccess {String} name 产品名称
     * @apiSuccess {String} marketMerchantName 所属商家
     * @apiSuccess {String=GOODS("商品"), SERVICE("服务")} type 产品类型
     * @apiSuccess {Double} basePrice 原价
     * @apiSuccess {Double} sellPrice 标准价格
     * @apiSuccess {boolean} refundable 是否过期退
     * @apiSuccess {Long} saleCount 售出数
     * @apiSuccess {Double} settleNum 核销数
     * @apiSuccess {Double} settleAmount 结算总金额
     * @apiSuccess {Double} serveFee 平台总服务费
     * @apiSuccess {Double} shareFee 分享返利
     * @apiSuccess {Double} resellFee 分销佣金
     * @apiSuccess {Double} sumResellFee 总佣金
     * @apiSuccess {Double} sumShareFee 总返利
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功",
     * "data": [
     *      {
     *          "id": 3,
     *          "name": "水电费",
     *          "marketMerchantName": "香啊粑粑",
     *          "refundable": "false",
     *          "type": "SERVICE",
     *          "basePrice": "22.34",
     *          "sellPrice": "22.34",
     *          "saleCount": 234,
     *          "settleNum": 230,
     *          "settleAmount": 124,
     *          "serveFee": 33,
     *          "buyerFee": 234,
     *          "resellFee": 234,
     *          "resellRate": 234,
     *          "sumResellFee": 234,
     *          "sumShareFee": 234,
     *          "shareFee": 23
     *      },
     *      ......
     *   ]
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_INCOME_COLLECT_PAGE, method = RequestMethod.GET)
    public JsonResult incomeCollectPage(HttpServletRequest request, SettlementRecordDto dto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (StringUtils.isNotBlank(dto.getProductType()) && !EnumUtils.isValidEnum(ProductType.class, dto.getProductType())) {
                jsonResult.remind("产品类型只允许 ALL(\"全部\"), GOODS(\"商品\"), SERVICE(\"服务\")\"",log);
                return;
            }

            if (StringUtils.isNotBlank(dto.getProductSource()) && !EnumUtils.isValidEnum(MerchantOrderSourceType.class, dto.getProductSource())) {
                jsonResult.remind("产品来源只允许 ALL(\"全部\"), MARKET(\"分销收入\"), SELF(\"自营收入\")",log);
                return;
            }

            PageResult<ProductDto> pageResult = merchantProductRepository.findProductIncomeCollectPage(dto.getProductSource(), dto.getProductType(), dto.getBeginDate(), dto.getEndDate(), dto.getKeyword(), dto.getRefundable(), userInfoDto.mall.getId(), userInfoDto.merchant.getId(), this.getPage(dto.getPageNo(), dto.getPageSize()));

            pageResult.data.stream().map(product -> {
                Long saleCount = 0L;//售出数
                Long settleCount = 0L;//核销数
                BigDecimal settleAmount = BigDecimal.ZERO; //实收金额
                BigDecimal sumResellFee = BigDecimal.ZERO; //佣金
                BigDecimal sumShareFee = BigDecimal.ZERO; //分享返利
                BigDecimal serveFee = BigDecimal.ZERO; //平台服务费
                List<MerchantOrderItem> merchantOrderItem = merchantOrderItemRepository.findByProductIdAndMerchantIdAndMallId(product.getId(), userInfoDto.merchant.getId(), userInfoDto.mall.getId());
                for (MerchantOrderItem orderItem : merchantOrderItem) {
                    saleCount = saleCount + orderItem.getBuyCount();
                    MerchantOrder merchantOrder = merchantOrderRepository.findByOrderNumAndMerchantIdAndMallId(orderItem.getMerchantOrderNum(), orderItem.getMerchantId(), orderItem.getMallId());
                    Long verifyCount = orderItem.getVerifyCount();
                    if (orderItem.getSettleStatus() == SettlementStatus.SETTLED) {
                        verifyCount = orderItem.getBuyCount();
                    }
                    if (orderItem.getProductRefundable() == Whether.NO) {
                        verifyCount = orderItem.getBuyCount();
                    }
                    if (merchantOrder.getGiftPacketId() != null && orderItem.getProductRefundable() == Whether.NO && merchantOrder.getSettleStatus() != SettlementStatus.SETTLED) {
                        verifyCount = 0L;
                    }

                    if ((orderItem.getVerifyCount() > 0 && merchantOrder.getGiftPacketId() == null) || (orderItem.getProductRefundable() == Whether.NO && merchantOrder.getOrderType() == OrderType.SERVICE && (merchantOrder.getSettleStatus() == SettlementStatus.SETTLED || merchantOrder.getSettleStatus() == SettlementStatus.PART_SETTLE)) || (orderItem.getVerifyCount() > 0 && merchantOrder.getGiftPacketId() != null && merchantOrder.getSettleStatus() == SettlementStatus.SETTLED)) {

                        if (MerchantOrderPathType.B2D2C2C == orderItem.getPathType() && MerchantOrderMerchantRole.DISTRIBUTOR == orderItem.getMerchantRole()) {
                            BigDecimal singleShareFee = BigDecimalUtils.divide(orderItem.getShareFee(), new BigDecimal(orderItem.getBuyCount()));
                            sumShareFee = sumShareFee.add(singleShareFee.multiply(new BigDecimal(verifyCount)));
                        }

                        BigDecimal singleSettleAmount = BigDecimalUtils.divide(orderItem.getDiscountAmount(), new BigDecimal(orderItem.getBuyCount()));
                        settleAmount = settleAmount.add(singleSettleAmount.multiply(new BigDecimal(verifyCount)));
                        settleCount = settleCount + orderItem.getVerifyCount();

                        if (MerchantOrderPathType.B2D2C == orderItem.getPathType() || MerchantOrderPathType.B2D2C2C == orderItem.getPathType()) {
                            BigDecimal singleResell = BigDecimalUtils.divide(orderItem.getResellFee(), new BigDecimal(orderItem.getBuyCount()));
                            sumResellFee = sumResellFee.add(singleResell.multiply(new BigDecimal(verifyCount)));
                        }

                        if (MerchantOrderPathType.B2C2C == orderItem.getPathType()) {
                            BigDecimal singleShareFee = BigDecimalUtils.divide(orderItem.getShareFee(), new BigDecimal(orderItem.getBuyCount()));
                            sumShareFee = sumShareFee.add(singleShareFee.multiply(new BigDecimal(verifyCount)));
                        }
                        if (MerchantOrderSourceType.SELF == MerchantOrderSourceType.valueOf(dto.getProductSource())) {
                            BigDecimal mallServiceFeeRates = BigDecimalUtils.divide(new BigDecimal(orderItem.getServeRate()), BigDecimal.valueOf(100));
                            BigDecimal totalServeFee = orderItem.getDiscountAmount().multiply(mallServiceFeeRates);
                            BigDecimal singleServeFee = BigDecimalUtils.divide(totalServeFee, new BigDecimal(orderItem.getBuyCount()));
                            serveFee = serveFee.add(singleServeFee.multiply(new BigDecimal(verifyCount)));
                        }
                    }
                }
                product.setSettleAmount(Double.valueOf(settleAmount.toString()));
                product.setSumResellFee(Double.valueOf(sumResellFee.toString()));
                product.setSettleNum(settleCount);
                product.setSumShareFee(Double.valueOf(sumShareFee.toString()));
                product.setServeFee(Double.valueOf(serveFee.toString()));
                product.setSaleCount(saleCount);
                return product;
            }).collect(Collectors.toList());
            pageResult.setUrl(Routes.MERCHANT_INCOME_COLLECT_PAGE);
            jsonResult.data = pageResult;
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/income/collect/sum 收入汇总 总计
     * @apiGroup MERCHANT_INCOME_COLLECT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String=ALL("全部"), GOODS("商品"), SERVICE("服务")} productType <code>必传参数</code> 产品类型 默认ALL
     * @apiParam {String=MARKET("分销收入"), SELF("自营收入")} productSource <code>必传参数</code> 产品来源 默认SELF
     * @apiParam {String} beginDate  开始时间
     * @apiParam {String} endDate  结束时间
     * @apiParam {String} keyword  产品名称/编号
     *
     * @apiSuccess {Long} buyCount 售出数
     * @apiSuccess {Long} settleNum 核销数
     * @apiSuccess {Double} settleAmount 结算总金额
     * @apiSuccess {Double} serveFee 平台总服务费
     * @apiSuccess {Double} shareFee 分享者总返利
     * @apiSuccess {Double} resellFee 分销佣金
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功",
     * "data":
     *      {
     *          "buyCount": 234,
     *          "settleNum": 230,
     *          "settleAmount": 124,
     *          "serveFee": 33,
     *          "resellFee": 234,
     *          "shareFee": 23
     *     }
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_INCOME_COLLECT_SUM, method = RequestMethod.GET)
    public JsonResult incomeCollectSum(HttpServletRequest request, SettlementRecordDto dto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (StringUtils.isNotBlank(dto.getProductType()) && !EnumUtils.isValidEnum(ProductType.class, dto.getProductType())) {
                jsonResult.remind("产品类型只允许 ALL(\"全部\"), GOODS(\"商品\"), SERVICE(\"服务\")\"",log);
                return;
            }

            if (StringUtils.isNotBlank(dto.getProductSource()) && !EnumUtils.isValidEnum(MerchantOrderSourceType.class, dto.getProductSource())) {
                jsonResult.remind("产品来源只允许 MARKET(\"分销收入\"), SELF(\"自营收入\")",log);
                return;
            }

            List<ProductDto> productList = merchantProductRepository.findIncomeCollectSum(dto.getProductSource(), dto.getProductType(), dto.getBeginDate(), dto.getEndDate(), dto.getKeyword(), dto.getRefundable(), userInfoDto.mall.getId(), userInfoDto.merchant.getId());
            SettlementRecordDto settlementRecordDto = new SettlementRecordDto();

            Long saleCount = 0L;//售出数
            Long settleCount = 0L;//核销数
            BigDecimal settleAmount = BigDecimal.ZERO;
            BigDecimal serveFee = BigDecimal.ZERO;
            BigDecimal shareFee = BigDecimal.ZERO;
            BigDecimal resellFee = BigDecimal.ZERO;
            for (ProductDto productDto : productList) {
                List<MerchantOrderItem> merchantOrderItem = merchantOrderItemRepository.findByProductIdAndMerchantIdAndMallId(productDto.getId(), userInfoDto.merchant.getId(), userInfoDto.mall.getId());
                for (MerchantOrderItem orderItem : merchantOrderItem) {
                    MerchantOrder merchantOrder = merchantOrderRepository.findByOrderNumAndMerchantIdAndMallId(orderItem.getMerchantOrderNum(), orderItem.getMerchantId(), orderItem.getMallId());
                    saleCount = saleCount + orderItem.getBuyCount();
                    Long verifyCount = orderItem.getVerifyCount();
                    if (orderItem.getSettleStatus() == SettlementStatus.SETTLED) {
                        verifyCount = orderItem.getBuyCount();
                    }
                    if (orderItem.getProductRefundable() == Whether.NO) {
                        verifyCount = orderItem.getBuyCount();
                    }

                    if (merchantOrder.getGiftPacketId() != null && orderItem.getProductRefundable() == Whether.NO && merchantOrder.getSettleStatus() != SettlementStatus.SETTLED) {
                        verifyCount = 0L;
                    }

                    if ((orderItem.getVerifyCount() > 0 && merchantOrder.getGiftPacketId() == null) || (orderItem.getProductRefundable() == Whether.NO && merchantOrder.getOrderType() == OrderType.SERVICE && (merchantOrder.getSettleStatus() == SettlementStatus.SETTLED || merchantOrder.getSettleStatus() == SettlementStatus.PART_SETTLE)) || (orderItem.getVerifyCount() > 0 && merchantOrder.getGiftPacketId() != null && merchantOrder.getSettleStatus() == SettlementStatus.SETTLED)) {

                        BigDecimal singleSettleAmount = BigDecimalUtils.divide(orderItem.getDiscountAmount(), new BigDecimal(orderItem.getBuyCount()));
                        settleAmount = settleAmount.add(singleSettleAmount.multiply(new BigDecimal(verifyCount)));
                        settleCount = settleCount + orderItem.getVerifyCount();

                        if (MerchantOrderPathType.B2D2C2C == orderItem.getPathType() && MerchantOrderMerchantRole.DISTRIBUTOR == orderItem.getMerchantRole()) {
                            BigDecimal singleShareFee = BigDecimalUtils.divide(orderItem.getShareFee(), new BigDecimal(orderItem.getBuyCount()));
                            shareFee = shareFee.add(singleShareFee.multiply(new BigDecimal(verifyCount)));
                        }

                        if (MerchantOrderPathType.B2D2C == orderItem.getPathType() || MerchantOrderPathType.B2D2C2C == orderItem.getPathType()) {
                            BigDecimal singleResell = BigDecimalUtils.divide(orderItem.getResellFee(), new BigDecimal(orderItem.getBuyCount()));
                            resellFee = resellFee.add(singleResell.multiply(new BigDecimal(verifyCount)));
                        }

                        if (MerchantOrderPathType.B2C2C == orderItem.getPathType()) {
                            BigDecimal singleShareFee = BigDecimalUtils.divide(orderItem.getShareFee(), new BigDecimal(orderItem.getBuyCount()));
                            shareFee = shareFee.add(singleShareFee.multiply(new BigDecimal(verifyCount)));
                        }
                        if (MerchantOrderSourceType.SELF == MerchantOrderSourceType.valueOf(dto.getProductSource())) {
                            BigDecimal mallServiceFeeRates = BigDecimalUtils.divide(new BigDecimal(orderItem.getServeRate()), BigDecimal.valueOf(100));
                            BigDecimal totalServeFee = orderItem.getDiscountAmount().multiply(mallServiceFeeRates);
                            BigDecimal singleServeFee = BigDecimalUtils.divide(totalServeFee, new BigDecimal(orderItem.getBuyCount()));
                            serveFee = serveFee.add(singleServeFee.multiply(new BigDecimal(verifyCount)));
                        }

                    }
                }
            }
            settlementRecordDto.setBuyCount(saleCount);
            settlementRecordDto.setSettleAmount(Double.valueOf(settleAmount.toString()));
            settlementRecordDto.setServeFee(Double.valueOf(serveFee.toString()));
            settlementRecordDto.setSettleNum(settleCount);
            settlementRecordDto.setShareFee(Double.valueOf(shareFee.toString()));
            settlementRecordDto.setResellFee(Double.valueOf(resellFee.toString()));
            jsonResult.data = settlementRecordDto;
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/income/collect/info/page 收入汇总明细 分页
     * @apiGroup MERCHANT_INCOME_COLLECT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {Long} productId <code>必传参数</code></code> 产品ID
     * @apiParam {String=MARKET("分销收入"), SELF("自营收入")} productSource <code>必传参数</code></code> 产品类型
     *
     * @apiSuccess {String=B2C("自有渠道"), B2C2C("粉丝分享"), B2D2C("分销市场"), B2D2C2C("粉丝分享")'} pathType 售出数
     * @apiSuccess {date} lastUpdated 时间
     * @apiSuccess {Long} customerName 购买者
     * @apiSuccess {Double} singleAmount 实际售价
     * @apiSuccess {Double} settleNum 核销数
     * @apiSuccess {Double} serveRate 平台服务费
     * @apiSuccess {Double} discountAmount 实收金额
     * @apiSuccess {Double} shareFee 返利
     * @apiSuccess {Double} resellFee 佣金
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功",
     * "data":[
     *      {
     *          "pathType": "B2C",
     *          "singleAmount": 234,
     *          "settleNum": 230,
     *          "serveFee": 33,
     *          "resellFee": 33,
     *          "discountAmount": 234,
     *          "serveRate": 234,
     *          "customerName": "占三",
     *          "lastUpdated": "2016-12-23",
     *          "shareFee": 23
     *     }
     *     .....
     *   ]
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_INCOME_COLLECT_INFO_PAGE, method = RequestMethod.GET)
    public JsonResult incomeCollectInfoPage(HttpServletRequest request, SettlementRecordDto dto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (dto.getProductId() == null) {
                jsonResult.remind("产品ID 不能为空",log);
                return;
            }
            if (StringUtils.isBlank(dto.getProductSource())) {
                jsonResult.remind("产品产品类型 不能为空",log);
                return;
            }
            PageResult<MerchantOrderItemDto> pageResult = merchantOrderItemRepository.findIncomeCollectInfoPage(dto.getProductId(), userInfoDto.mall.getId(), userInfoDto.merchant.getId(), this.getPage(dto.getPageNo(), dto.getPageSize()));
            pageResult.data.stream().map(orderItem -> {
                Long verifyCount = orderItem.getVerifyCount();
                if (SettlementStatus.valueOf(orderItem.getSettleStatus()) == SettlementStatus.SETTLED) {
                    verifyCount = orderItem.getBuyCount();
                }
                if (orderItem.getProductRefundable() == Whether.NO) {
                    verifyCount = orderItem.getBuyCount();
                }
                MerchantOrder merchantOrder = merchantOrderRepository.findByOrderNumAndMerchantIdAndMallId(orderItem.getMerchantOrderNum(), orderItem.getMerchantId(), orderItem.getMallId());
                if (merchantOrder.getGiftPacketId() != null && orderItem.getProductRefundable() == Whether.NO && merchantOrder.getSettleStatus() != SettlementStatus.SETTLED) {
                    verifyCount = 0L;
                }
                if ((orderItem.getVerifyCount() > 0 && merchantOrder.getGiftPacketId() == null) || (orderItem.getProductRefundable() == Whether.NO && merchantOrder.getOrderType() == OrderType.SERVICE) || (orderItem.getVerifyCount() > 0 && merchantOrder.getGiftPacketId() != null && merchantOrder.getSettleStatus() == SettlementStatus.SETTLED)) {

                    //实收金额
                    BigDecimal singlePrice = BigDecimalUtils.divide(orderItem.getDiscountAmount(), new BigDecimal(orderItem.getBuyCount()));


                    //服务费
                    BigDecimal mallServiceFeeRates = BigDecimalUtils.divide(new BigDecimal(orderItem.getServeRate()), BigDecimal.valueOf(100));
                    BigDecimal totalServeFee = orderItem.getDiscountAmount().multiply(mallServiceFeeRates);
                    BigDecimal singleServeFee = BigDecimalUtils.divide(totalServeFee, new BigDecimal(orderItem.getBuyCount()));
                    orderItem.setServeRate(singleServeFee.multiply(new BigDecimal(verifyCount)).toString());

                    //返利
                    BigDecimal singleShareFee = BigDecimalUtils.divide(orderItem.getShareFee(), new BigDecimal(orderItem.getBuyCount()));
                    orderItem.setShareFee(singleShareFee.multiply(new BigDecimal(verifyCount)));

                    //佣金
                    BigDecimal singleResell = BigDecimalUtils.divide(orderItem.getResellFee(), new BigDecimal(orderItem.getBuyCount()));
                    orderItem.setResellFee(singleResell.multiply(new BigDecimal(verifyCount)));
                    orderItem.setDiscountAmount(singlePrice.multiply(new BigDecimal(verifyCount)));

                    if (MerchantOrderPathType.B2D2C2C == MerchantOrderPathType.valueOf(orderItem.getPathType()) && MerchantOrderSourceType.SELF == MerchantOrderSourceType.valueOf(dto.getProductSource())) {
                        orderItem.setShareFee(BigDecimal.ZERO);
                    }
                    if (MerchantOrderPathType.B2C2C == MerchantOrderPathType.valueOf(orderItem.getPathType())) {
                        orderItem.setResellFee(BigDecimal.ZERO);
                    }
                    if (MerchantOrderPathType.B2C == MerchantOrderPathType.valueOf(orderItem.getPathType())) {
                        orderItem.setResellFee(BigDecimal.ZERO);
                        orderItem.setShareFee(BigDecimal.ZERO);
                    }
                    if (MerchantOrderPathType.B2D2C == MerchantOrderPathType.valueOf(orderItem.getPathType())) {
                        orderItem.setShareFee(BigDecimal.ZERO);
                    }
                }
                return orderItem;
            }).collect(Collectors.toList());
            pageResult.setUrl(Routes.MERCHANT_INCOME_COLLECT_INFO_PAGE);
            jsonResult.data = pageResult;
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/income/collect/info/sum 收入汇总明细 总计
     * @apiGroup MERCHANT_INCOME_COLLECT
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {Long} productId <code>必传参数</code></code> 产品ID
     * @apiParam {Long} productSource <code>必传参数</code></code> 产品类型
     *
     * @apiSuccess {Long} buyCount 售出数
     * @apiSuccess {Double} settleNum 核销数
     * @apiSuccess {Double} settleAmount 结算总金额
     * @apiSuccess {Double} serveFee 平台总服务费
     * @apiSuccess {Double} buyerFee 购买者总返利
     * @apiSuccess {Double} shareFee 分享者总返利
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功",
     * "data": [
     *      {
     *          "buyCount": 234,
     *          "settleNum": 230,
     *          "settleAmount": 124,
     *          "serveFee": 33,
     *          "buyerFee": 234,
     *          "shareFee": 23
     *      },
     *      ......
     *   ]
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_INCOME_COLLECT_INFO_SUM, method = RequestMethod.GET)
    public JsonResult incomeCollectInfoSum(HttpServletRequest request, SettlementRecordDto dto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (dto.getProductId() == null) {
                jsonResult.remind("产品ID 不能为空",log);
                return;
            }
            if (StringUtils.isBlank(dto.getProductSource())) {
                jsonResult.remind("产品产品类型 不能为空",log);
                return;
            }
            List<MerchantOrderItem> merchantOrderItemList = merchantOrderItemRepository.findByProductIdAndMerchantIdAndMallIdAndSettleStatusNot(dto.getProductId(), userInfoDto.merchant.getId(), userInfoDto.mall.getId(), SettlementStatus.WAIT_SETTLE);
            Long saleCount = 0L;//售出数
            Long settleCount = 0L;//核销数
            BigDecimal settleAmount = BigDecimal.ZERO;
            BigDecimal serveFee = BigDecimal.ZERO;
            BigDecimal shareFee = BigDecimal.ZERO;
            BigDecimal resellFee = BigDecimal.ZERO;
            for (MerchantOrderItem orderItem : merchantOrderItemList) {
                saleCount = saleCount + orderItem.getBuyCount();
                Long verifyCount = orderItem.getVerifyCount();
                if (orderItem.getSettleStatus() == SettlementStatus.SETTLED) {
                    verifyCount = orderItem.getBuyCount();
                }
                if (orderItem.getProductRefundable() == Whether.NO) {
                    verifyCount = orderItem.getBuyCount();
                }

                MerchantOrder merchantOrder = merchantOrderRepository.findByOrderNumAndMerchantIdAndMallId(orderItem.getMerchantOrderNum(), orderItem.getMerchantId(), orderItem.getMallId());

                if (merchantOrder.getGiftPacketId() != null && orderItem.getProductRefundable() == Whether.NO && merchantOrder.getSettleStatus() != SettlementStatus.SETTLED) {
                    verifyCount = 0L;
                }
                if ((orderItem.getVerifyCount() > 0 && merchantOrder.getGiftPacketId() == null) || (orderItem.getProductRefundable() == Whether.NO && merchantOrder.getOrderType() == OrderType.SERVICE) || (orderItem.getVerifyCount() > 0 && merchantOrder.getGiftPacketId() != null && merchantOrder.getSettleStatus() == SettlementStatus.SETTLED)) {
                    BigDecimal singleSettleAmount = BigDecimalUtils.divide(orderItem.getDiscountAmount(), new BigDecimal(orderItem.getBuyCount()));
                    settleAmount = settleAmount.add(singleSettleAmount.multiply(new BigDecimal(verifyCount)));
                    settleCount = settleCount + orderItem.getVerifyCount();

                    if (MerchantOrderPathType.B2D2C2C == orderItem.getPathType() && MerchantOrderMerchantRole.DISTRIBUTOR == orderItem.getMerchantRole()) {
                        BigDecimal singleShareFee = BigDecimalUtils.divide(orderItem.getShareFee(), new BigDecimal(orderItem.getBuyCount()));
                        shareFee = shareFee.add(singleShareFee.multiply(new BigDecimal(verifyCount)));
                    }

                    if (MerchantOrderPathType.B2C2C == orderItem.getPathType()) {
                        BigDecimal singleShareFee = BigDecimalUtils.divide(orderItem.getShareFee(), new BigDecimal(orderItem.getBuyCount()));
                        shareFee = shareFee.add(singleShareFee.multiply(new BigDecimal(verifyCount)));
                    }

                    if (MerchantOrderPathType.B2D2C == orderItem.getPathType() || MerchantOrderPathType.B2D2C2C == orderItem.getPathType()) {
                        BigDecimal singleResell = BigDecimalUtils.divide(orderItem.getResellFee(), new BigDecimal(orderItem.getBuyCount()));
                        resellFee = resellFee.add(singleResell.multiply(new BigDecimal(verifyCount)));
                    }

                    BigDecimal mallServiceFeeRates = BigDecimalUtils.divide(new BigDecimal(orderItem.getServeRate()), BigDecimal.valueOf(100));
                    BigDecimal totalServeFee = orderItem.getDiscountAmount().multiply(mallServiceFeeRates);
                    BigDecimal singleServeFee = BigDecimalUtils.divide(totalServeFee, new BigDecimal(orderItem.getBuyCount()));
                    BigDecimal sServeFee = singleServeFee.multiply(new BigDecimal(verifyCount));
                    serveFee = serveFee.add(sServeFee);
                }
            }
            dto.setBuyCount(saleCount);
            dto.setSettleAmount(Double.valueOf(settleAmount.toString()));
            dto.setServeFee(Double.valueOf(serveFee.toString()));
            dto.setSettleNum(settleCount);
            dto.setShareFee(Double.valueOf(shareFee.toString()));
            dto.setResellFee(Double.valueOf(resellFee.toString()));
            jsonResult.data = dto;
        };
        return doing.go(request, log);
    }
}
